package rmi.chat.client;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.rmi.*;
import java.rmi.server.*;

import rmi.chat.server.Server;

public class ChatClient extends JApplet implements Receiver, ActionListener{
	private String login_name="";
	private boolean isApplet, loggedIn;
	private static final int LOGIN=1, LOGOUT=2, CLEAR=3, COLOR=4, OK=5, CANCEL=6, BLUE=7, GREEN=8,
			BLACK=9;
	private JButton jb_logout, jb_login, jb_clear, jb_color, jb_ok, jb_cancel, jb_blue, jb_green, 
	jb_black;
	private JTextArea jta_chatDisplay;
	private JTextField jtf_chat_string, jtf_avatar_name;
	private JDialog jd_chat_name, jd_chat_color;
	private JScrollPane scrollPane;
	private Server server = null;
	public ChatClient() throws RemoteException{
		UnicastRemoteObject.exportObject(this, 2020);
	}
	
	@Override
	public void destroy(){
		try{
			if(server != null) server.removeReceiver(this);
		}catch(RemoteException e){}
	}
	
	public void createComponents(){
		jb_logout = new JButton("Log Out");
		jb_login = new JButton("Log In");
		jb_clear = new JButton("Clear Message");
		jb_color = new JButton("COLOR");
		jb_blue = new JButton("BLUE");
		jb_green = new JButton("GREEN");
		jb_black = new JButton("BLACK");
		jb_ok = new JButton("OK");
		jb_cancel = new JButton("Cancel");
		jtf_avatar_name = new JTextField();
		jtf_chat_string = new JTextField();
		jd_chat_name = new JDialog();
		jd_chat_color = new JDialog();
		jta_chatDisplay = new JTextArea();
	}
	
	public void initUI(){
		createComponents();
		jb_logout.setActionCommand(LOGOUT +"");
		jb_login.setActionCommand(LOGIN +"");
		jb_clear.setActionCommand(CLEAR +"");
		jb_color.setActionCommand(COLOR +"");
		jb_blue.setActionCommand(BLUE +"");
		jb_green.setActionCommand(GREEN +"");
		jb_black.setActionCommand(BLACK +"");
		jb_ok.setActionCommand(OK +"");
		jb_cancel.setActionCommand(CANCEL +"");
		jb_login.setToolTipText("login with new chat name");
		jb_logout.setToolTipText("logout chatRoom");
		jb_clear.setToolTipText("clear chat messages since started...");
		jb_color.setToolTipText("changed color!");
		jd_chat_color.setTitle("changed color!!");
		jd_chat_name.setTitle("Input Avatar Name");
		jd_chat_name.setTitle("Select Color");
		
		JPanel color = new JPanel();
		color.add(jb_blue);
		color.add(jb_green);
		color.add(jb_black);
		color.add(new Label("Color changed!!"));
		jd_chat_color.getContentPane().add(color, BorderLayout.CENTER);
		jd_chat_color.pack();
		JPanel dummy = new JPanel();
		dummy.add(jb_ok);
		dummy.add(jb_cancel);
		JPanel p = new JPanel();
		p.add(new Label("Avatar Name : "));
		p.add(jtf_avatar_name);
		jd_chat_name.getContentPane().add(p, BorderLayout.NORTH);
		jd_chat_name.getContentPane().add(dummy, BorderLayout.SOUTH);
		jd_chat_name.pack();
		jta_chatDisplay.setBackground(Color.pink);
		jta_chatDisplay.setForeground(Color.green);
		jta_chatDisplay.append("반갑소");
		jta_chatDisplay.append("사용법 = 입장 : Click 'Log in', 퇴실 : 'Log Out' \n");
		jta_chatDisplay.setEditable(false);
		jb_logout.setEnabled(false);
		
		JPanel tmpPanel = new JPanel();
		tmpPanel.add(jb_login);
		tmpPanel.add(jb_logout);
		tmpPanel.add(jb_clear);
		tmpPanel.add(jb_color);
		scrollPane = new JScrollPane(jta_chatDisplay);
		Container contentPane = getContentPane();
		contentPane.setLayout(new BorderLayout());
		contentPane.add(tmpPanel, BorderLayout.NORTH);
		contentPane.add(scrollPane, BorderLayout.CENTER);
		contentPane.add(jtf_chat_string, BorderLayout.SOUTH);
	}
	
	private void addListener(){
		ActionListener tf_listener = new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				if(!loggedIn){
					jtf_chat_string.setText("Please Login First...");
					return;
				}
				try{
					send(jtf_chat_string.getText());
					jtf_chat_string.setText("");
				}catch(RemoteException ex){
					ex.printStackTrace();
				}
			}
		};
		jb_logout.addActionListener(this);
		jb_login.addActionListener(this);
		jb_clear.addActionListener(this);
		jb_color.addActionListener(this);
		jb_blue.addActionListener(this);
		jb_green.addActionListener(this);
		jb_black.addActionListener(this);
		jb_ok.addActionListener(this);
		jb_cancel.addActionListener(this);
		jtf_chat_string.addActionListener(tf_listener);
	}
	
	private void openConnection() throws RemoteException{
		if(server == null){
			try{
				server = (Server)Naming.lookup("rmi://localhost:2000/ChatServer");
				System.out.println("Lookup Up Remote Object...");
				server.addReceiver(this);
				send(login_name + " entered ... \n");
				loggedIn = true;
			}catch(Exception e){
				throw new RemoteException("Couldn't get a valid remote reference...["+ e +"]");
			}
		}
		jb_logout.setEnabled(false);
		jb_login.setEnabled(true);
		jb_color.setEnabled(true);
		jb_blue.setEnabled(true);
		jb_green.setEnabled(true);
		jb_black.setEnabled(true);
		jtf_chat_string.requestFocus();
		jtf_chat_string.setText(" ");
	}
	
	private void closeConnection() throws RemoteException
	{
		server.broadcast(" " + login_name + "님이 퇴실 하셨습니다..");
		server.removeReceiver(this);
		loggedIn = false;
		server = null;
		jb_logout.setEnabled(false);
		jb_login.setEnabled(true);
		jb_color.setEnabled(true);
		jb_blue.setEnabled(true);
		jb_green.setEnabled(true);
		jb_black.setEnabled(true);
	}
	
	private void go(){
		JFrame jf = new JFrame();
		jf.getContentPane().add(this);
		initUI();
		isApplet = false;
		jf.setSize(400, 600);
		jf.setVisible(true);
		jf.addWindowListener(new WindowCloser());
	}
	
	private void send(String msg) throws RemoteException{
		server.broadcast("[" + login_name + "]" + msg);
		jtf_chat_string.setText("");
	}
	
	public void printMsg(String msg) throws RemoteException{
		jta_chatDisplay.append(msg+"\n");
		JScrollBar vScroll = null;
		vScroll = scrollPane.getVerticalScrollBar();
		vScroll.setValue(vScroll.getMaximum());
	}
	
	public static void main(String [] args){
		try{
			new ChatClient().go();
		}catch(RemoteException ex){
			ex.printStackTrace();
		}
	}
	
	class WindowCloser extends WindowAdapter{
		@Override
		public void windowClosing(WindowEvent we){
			if(server != null){
				try{
					closeConnection();
				}catch(RemoteException e){
					e.printStackTrace();
				}
			}
			System.exit(0);
		}
	}
	
	@Override
	public void actionPerformed(ActionEvent ae){
		int buttonId = Integer.parseInt(ae.getActionCommand());
		switch(buttonId){
		case LOGOUT:
			try{
				closeConnection();
			}catch(RemoteException e){
				e.printStackTrace();
			}
			break;
		case LOGIN:
			jd_chat_name.setLocation(ChatClient.this.getLocationOnScreen().x + 50, 
					ChatClient.this.getLocationOnScreen().y + 50);
			jd_chat_color.setVisible(true);
			break;
		
		case COLOR:
			jd_chat_color.setLocation(ChatClient.this.getLocationOnScreen().x + 50, 
					ChatClient.this.getLocationOnScreen().y + 50);
			jd_chat_color.setVisible(true);
			break;
		case BLUE:
			jta_chatDisplay.setForeground(Color.blue);
			jd_chat_color.setVisible(false);
			break;
		case GREEN:
			jta_chatDisplay.setForeground(Color.green);
			jd_chat_color.setVisible(false);
			break;
		case BLACK:
			jta_chatDisplay.setForeground(Color.black);
			jd_chat_color.setVisible(false);
			break;
		case OK:
			login_name = jtf_avatar_name.getText();
			try{
				openConnection();
				jta_chatDisplay.setText("Hello \n" + login_name + "으로 로그인 하셨습니다.");
				jd_chat_name.setVisible(false);
			}catch(RemoteException e) {
				e.printStackTrace();
			}
			break;
		case CANCEL:
			jd_chat_name.setVisible(false);
			break;
		case CLEAR:
			jta_chatDisplay.setText("Cleard the display area. \n");
			break;
		}
	}
}
